package visitor.pattern.mysonar;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.formatter.Token;
import org.eclipse.jdt.internal.formatter.TokenManager;

import java.util.List;

/**
 * @Author: Coderlyz
 * @Date: 2023/4/13 14:55
 */

@Slf4j
public class DoNotThrowAtFinallyBlockCheck {
    private CompilationUnit unit;
    private Problems problemList;
    private TokenManager tokenManage;

    public DoNotThrowAtFinallyBlockCheck(CompilationUnit tree, TokenManager tokenManager){
        this.unit = tree;
        this.problemList = new Problems();
        this.tokenManage = tokenManager;
    }

    public void doCheck(){
        List types = unit.types();

        for(Object obj : types){
            ASTNode astNode = (ASTNode) obj;
            astNode.accept(new ASTVisitor() {
                @Override
                public boolean visit(TryStatement node) {
                    Block aFinally = node.getFinally();
                    List statements = aFinally.statements();
                    for (int j = 0; j < statements.size(); j++) {
                        ExpressionStatement expressionStatement = (ExpressionStatement) statements.get(j);
                        MethodInvocation expression = (MethodInvocation) expressionStatement.getExpression();
                        IMethodBinding iMethodBinding = expression.resolveMethodBinding();
                        ITypeBinding[] exceptionTypes = iMethodBinding.getExceptionTypes();
                        for (int i=0;i<exceptionTypes.length;i++){
                            //拿到token位置
                            int indexAfter = tokenManage.firstIndexIn(expression, TerminalTokens.TokenNameIdentifier);
                            Token token = tokenManage.get(indexAfter);
                            problemList.addProblem(unit.getLineNumber(token.originalStart),tokenManage.getSource().substring(token.originalStart,token.originalEnd+1)+"方法不应在finally中可能抛出异常");
                        }
                    }
                    return true;
                }
            });
            problemList.showProbles();
        }
    }
}
